﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PowerBooking.RSE.Domain.Models;
using PowerBooking.RSE.Utility.Helpers;
using System.Text.RegularExpressions;
using System.Collections.Concurrent;
using System.Data.Entity;
using PowerBooking.RSE.Poco;
using PowerBooking.RSE.IRepository;
using System.Threading.Tasks;
using PowerBooking.RSE.Contract.Enums;

namespace PowerBooking.RSE.Domain.Factories
{
    public class FilterFactory : Factory
    {
        public FilterFactory(IUnitOfWork unitOfWork) : base(unitOfWork) { }

        public List<Filter> GetFiltersByCityID(long cityID)
        {
            var filters = new ConcurrentBag<Filter>();
            var filterPocoList = UnitOfWork.FilterRepository.QueryFiltersByCityID(cityID);
            Parallel.ForEach(filterPocoList, (f) => { filters.Add(new Filter().InitDomain(f)); });
            return filters.ToList();
        }

        public List<Filter> CreateFilters(long spiderID, long cityID, string cityUrl)
        {
            var existFilterList = GetFiltersByCityID(cityID);
            var filterPocoList = new ConcurrentBag<FilterPoco>();
            var filters = new ConcurrentBag<Filter>();
            var url = cityUrl + "/sitemap";
            var html = WebRequestHelper.Get(url);

            var matches = Regex.Matches(html, GetSmallCategoryParttern(), RegexOptions.Singleline | RegexOptions.IgnoreCase).OfType<Match>().ToList();

            Parallel.ForEach(matches, (m, loopState) =>
            {

                if (SpiderMonitorStaticFactory.GetSpiderMonitor(spiderID).SpiderStatus != SpiderStatusEnum.Stop)
                {
                    filterPocoList.Add(CreateFilter(cityID, cityUrl, m));
                }
                else
                {
                    loopState.Stop();
                    return;
                }
            });

            if (matches.Count == 0)
            {
                matches = Regex.Matches(html, GetBigCategoryParttern(), RegexOptions.Singleline | RegexOptions.IgnoreCase).OfType<Match>().ToList();

                Parallel.ForEach(matches, (m, loopState) =>
                {
                    if (SpiderMonitorStaticFactory.GetSpiderMonitor(spiderID).SpiderStatus != SpiderStatusEnum.Stop)
                    {
                        filterPocoList.Add(CreateFilter(cityID, cityUrl, m));
                    }
                    else
                    {
                        loopState.Stop();
                        return;
                    }
                });
            }
            var filterPocos = filterPocoList.ToList();
            for (var i = 0; i < filterPocos.Count; i++)
            {
                if (!existFilterList.Exists(e => e.Url.Equals(filterPocos[i].Url, StringComparison.CurrentCultureIgnoreCase)))
                {
                    UnitOfWork.FilterRepository.InsertFilter(filterPocos[i]);
                }
            }
            Parallel.ForEach(filterPocos, (f) => { filters.Add(new Filter().InitDomain(f)); });
            existFilterList.AddRange(filters);
            return existFilterList;
        }

        private FilterPoco CreateFilter(long cityID, string cityUrl, Match match)
        {
            return new FilterPoco()
            {
                Name = match.Groups[2].Value,
                Url = cityUrl + RegexHelper.CheckStringLastChar("/", match.Groups[1].Value),
                CityID = cityID
            };
        }

        private string GetSmallCategoryParttern()
        {
            var parttern = string.Empty;
            var attributes = RegexHelper.CreateAttribute("target", "_blank") + RegexHelper.Space + RegexHelper.CreateAttribute("href", @"(/shop/search-s\d+_\d+/)") + RegexHelper.Space + RegexHelper.CreateAttribute("class", "g3");
            return RegexHelper.CreateDom("a", attributes, RegexHelper.AnyDomValueInGroup);
        }

        private string GetBigCategoryParttern()
        {
            var parttern = string.Empty;
            var attributes = RegexHelper.CreateAttribute("target", "_blank") + RegexHelper.Space + RegexHelper.CreateAttribute("href", @"(/shop/search-s\d+/)") + RegexHelper.Space + RegexHelper.CreateAttribute("class", "b g3");
            return RegexHelper.CreateDom("a", attributes, RegexHelper.AnyDomValueInGroup);
        }


    }
}
